package com.ysq.frame;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.Timer;

import com.ysq.start.ProgramRun;

/**
 * 主界面
 * @author Administrator
 *
 */
public class MainPanel extends JPanel implements ActionListener{
	private static final long serialVersionUID = 1L;
	public static final int panelWidth = 400;
	public static final int panelHeight = 400;
	public static final int blockSize = 20;	//正方框单元的宽度
	public Timer timer;
	public boolean isRunning;
	public int increaseX,increaseY;	//坐标的改变
	public JLabel speedLabel;	//速度
	public JLabel lengthLabel;	//长度
	public JLabel highestScoreLabel;	//最高分
	public JLabel statusJLabel;	//暂停，继续
	
	int maxX = panelWidth/blockSize;	//最大x坐标
	int maxY = panelHeight/blockSize;	//最大y坐标
	
	private int speed;
	int snakeLength;	//长度
	int highestScore;	//最高分数（长度）
	Point randomPoint;	//随机点坐标
	
	
	public int getSpeed() {
		return speed;
	}
	public void setSpeed(int speed) {
		speedLabel.setText("速度：" + speed);
		timer.setDelay(750 - (speed * 50));
		this.speed = speed;
	}
	
	Point snakeHead;	// snake head
	
	List<Point> bodyList = null;//snake body
	
	Random random = null;
	
	public MainPanel(){
		this.setLayout(null);
		this.setLocation(10, 10);
		this.setSize(new Dimension(panelWidth, panelHeight));
		this.random = new Random();
		
		speedLabel = new JLabel();
		speedLabel.setBounds(430, 20, 90, 20);
		this.add(speedLabel);
		
		lengthLabel = new JLabel();
		lengthLabel.setBounds(430, 50, 90, 20);
		this.add(lengthLabel);
		
		highestScoreLabel = new JLabel();
		highestScoreLabel.setBounds(430, 80, 90, 20);
		this.add(highestScoreLabel);
		
		statusJLabel = new JLabel();
		statusJLabel.setBounds(430, 110, 90, 20);
		this.add(statusJLabel);
		
		JLabel helpJLabel = new JLabel("提示：小键盘“+” “-”可改变速度");
		helpJLabel.setFont(new Font("Serief",0,11));
		helpJLabel.setForeground(Color.red);
		helpJLabel.setBounds(7, 410, 200, 20);
		this.add(helpJLabel);
		
		snakeHead = new Point();
		
		this.init();
	}
	/**
	 * 初始化
	 */
	public void init(){
		isRunning = true;
		speed = 6;
		speedLabel.setText("速度：" + speed);
		
		snakeLength = 1;
		lengthLabel.setText("长度：" + snakeLength);
		
		highestScore = ScoreUtil.getHighestScore();
		highestScoreLabel.setText("最高长度：" + highestScore);
		
		statusJLabel.setText("按P键暂停");
		
		increaseX = 1;
		increaseY = 0;
		
		snakeHead.x = 0;
		snakeHead.y = 0;
		
		bodyList = new ArrayList<Point>();
		
		//随机点
		randomPoint = createRandomPoint();
		
		timer = new Timer(750 - (speed * 50), this);
		timer.start();
	}
	
	/**
	 * 生成随机点
	 */
	public Point createRandomPoint(){
		//记录列号
		Set<Integer> colNumberSet = new HashSet<Integer>();
		//将所有的列号放入set
		for(int i = 0;i<maxX;i++){
			colNumberSet.add(i);
		}
		//列集合
		List<Set<Integer>> indexRowList = new ArrayList<Set<Integer>>();
		for(int i = 0;i<maxY;i++){
			Set<Integer> clonColSet = new HashSet<Integer>(colNumberSet);
			indexRowList.add(clonColSet);
		}
		//移除头所在的x坐标
		indexRowList.get(snakeHead.y).remove(snakeHead.x);
		
		//移除存在的坐标
		for(int i = 0;i<bodyList.size();i++){
			Point bodyPoint = bodyList.get(i);
			indexRowList.get(bodyPoint.y).remove(bodyPoint.x);
		}
		
		List<Integer> randomRowList = new ArrayList<Integer>();
		for(int i = 0;i<indexRowList.size();i++){
			if(!indexRowList.get(i).isEmpty()){
				randomRowList.add(i);
			}
		}
		int randomInt = random.nextInt(randomRowList.size());
		
		int randomY = randomRowList.get(randomInt);
		
		List<Integer> colList = new ArrayList<Integer>(indexRowList.get(randomY));
		
		randomInt = random.nextInt(colList.size());
		int randomX = colList.get(randomInt);
		
		Point randomPoint = new Point(randomX,randomY);
		return randomPoint;
	}
	
	/**
	 * 画主界面
	 * @param g
	 */
	public void drawMainPanel(Graphics g){
		int borderSize = 4;//主屏幕边框宽度
		g.setColor(new Color(238, 238, 238));
		g.fillRect(0, 0, ProgramRun.frameWidth,ProgramRun.frameHeight);
		
		g.setColor(Color.gray);
		for(int i=1;i<=borderSize;i++){
			g.drawRect(10 - i, 10-i, panelWidth + (i*2) - 1, panelHeight + (i*2) - 1);
		}
		g.setColor(Color.lightGray);
		g.fillRect(10, 10, panelWidth, panelHeight);
	}
	
	public void paint(Graphics g) {
		super.paint(g);
	}
	
	@Override
	public void paintComponent(Graphics g) {
		drawMainPanel(g);
		
		//画 随机点
		g.setColor(Color.BLUE);
		g.fill3DRect((randomPoint.x * blockSize) + 10, (randomPoint.y * blockSize) + 10, blockSize, blockSize, true);
		
		//画 head
		g.setColor(new Color(255, 255, 0));
		g.fill3DRect((snakeHead.x * blockSize) + 10, (snakeHead.y * blockSize) + 10, blockSize, blockSize, true);
		g.setColor(Color.RED);
		
		//画 body
		if(!bodyList.isEmpty()){
			for(int i = (bodyList.size() -1);i>=0;i--){
				Point bodyPoint = bodyList.get(i);
				g.fill3DRect((bodyPoint.x * blockSize) + 10, (bodyPoint.y * blockSize) + 10, blockSize, blockSize, true);
			}
		}
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		//先把 head 坐标加进 body，然后移除最后一个body
		bodyList.add(new Point(snakeHead.x,snakeHead.y));
		snakeHead.x += increaseX;
		snakeHead.y += increaseY;
		
		if(!snakeHead.equals(randomPoint) ){
			bodyList.remove(0);
		}else{
			snakeLength++;
			lengthLabel.setText("长度：" + snakeLength);
			randomPoint = createRandomPoint();
		}
		if(checkSnakeStatus()){
			repaint();
		}else{
			timer.stop();
			JOptionPane.showMessageDialog(null, "重新开始");
			this.init();
		}
	}
	
	/**
	 * 检测是否越界
	 * @return
	 */
	public boolean checkSnakeStatus(){
		boolean flag = true;
		int headX = snakeHead.x * 20;
		int headY = snakeHead.y * 20;
		if(headX >= panelWidth || headX < 0 || headY >= panelHeight || headY < 0){
			flag = false;
		}else{
			for(int i=0;i<bodyList.size();i++){
				if(snakeHead.equals(bodyList.get(i))){
					flag = false;
					break;
				}
			}
		}
		//设置最高分
		if(!flag){
			if(snakeLength > highestScore){
				ScoreUtil.setHighestScore(snakeLength);
			}
		}
		return flag;
	}
}
